<!--
 * @Author: early-autumn
 * @Date: 2020-05-14 11:24:49
 * @LastEditors: early-autumn
 * @LastEditTime: 2020-06-17 16:01:28
 -->
<template>
  <div>
    <div v-if="!disabled" class="top">
      <el-button-group>
        <el-button type="success" @click="work">正 常 班</el-button>
        <el-button type="warning" @click="rest">休 息</el-button>
      </el-button-group>
    </div>
    <el-table
      v-loading="loading"
      border
      :data="tableData"
      :cell-class-name="cellClassName"
      @cell-click="handleCellClick"
    >
      <el-table-column key="name" align="center" width="280">
        <template slot="header">
          <div class="header">
            <el-button
              icon="el-icon-arrow-left"
              plain
              circle
              @click="prev"
            ></el-button>
            <el-date-picker
              :value="currentWeek[0]"
              type="week"
              style="padding: 0 10px"
              format="yyyy 第 WW 星期"
              :editable="false"
              :clearable="false"
              :picker-options="pickerOptions"
              @input="change"
            />
            <el-button
              icon="el-icon-arrow-right"
              plain
              circle
              @click="next"
            ></el-button>
          </div>
        </template>
        <el-table-column key="name" label="诊所医生" align="center" width="280">
          <template slot-scope="scope">
            <div class="handler">
              {{ scope.row.userName }}
              <div v-if="endDay < today" class="mask"></div>
            </div>
          </template>
        </el-table-column>
      </el-table-column>
      <el-table-column
        v-for="week in weeks"
        :key="week.time"
        :label="week.time"
        align="center"
      >
        <el-table-column
          :key="week.time"
          align="center"
          :label="week.week"
          :prop="week.time"
        >
          <template slot-scope="scope">
            <div
              class="handler"
              :class="
                selectedData[scope.row.userId] &&
                selectedData[scope.row.userId][week.time] &&
                'actived'
              "
            >
              {{ scope.row.date[week.time] ? '休息' : '正常班' }}
              <div v-if="week.time < today" class="mask"></div>
            </div>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import dayjs from 'dayjs'
import { getThisWeekStartWithEnd } from '@/utils/date'
import { deepCopy } from '@/utils/utils'

export default {
  name: 'SchedulingTable',
  props: {
    loading: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    headerData: {
      type: Array,
      default: () => [],
    },
    contentData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      // 星期列表
      weeks: [],
      // 今天日期
      today: dayjs().format('YYYY-MM-DD'),
      // 周日日期
      endDay: dayjs().format('YYYY-MM-DD'),
      // 当前周起止时间
      currentWeek: getThisWeekStartWithEnd(),
      // 表格数据
      tableData: [],
      // 已选数据
      selectedData: {},
      //
      pickerOptions: {
        firstDayOfWeek: 1,
        shortcuts: [
          {
            text: '本周',
            onClick: (picker) => picker.$emit('pick', new Date()),
          },
        ],
      },
    }
  },
  watch: {
    headerData: {
      handler() {
        this.createTableData()
      },
      deep: true,
    },
    contentData: {
      handler() {
        this.createTableData()
      },
      deep: true,
    },
  },
  mounted() {
    this.createWeeks()
    this.change(this.today)
  },
  methods: {
    /**
     * 单元格样式
     */
    cellClassName(e) {
      let classs = 'cell-class-name '
      if (e.columnIndex === 0) {
        classs += 'name'
      } else {
        classs += e.row.date[e.column.property] ? 'normal' : 'rest'
      }
      return classs
    },
    /**
     * 选择单元格
     */
    handleCellClick(row, column) {
      if (this.disabled) {
        return
      }
      if (column.label === '诊所医生') {
        this.handleCellClickAll(row, column)
        return
      }
      if (column.property < this.today) {
        return
      }
      const selectedData = deepCopy(this.selectedData)
      selectedData[row.userId] = selectedData[row.userId] || {}
      if (selectedData[row.userId][column.property]) {
        delete selectedData[row.userId][column.property]
      } else {
        selectedData[row.userId][column.property] =
          row.date[column.property] || row.userName
      }
      this.selectedData = selectedData
    },
    /**
     * 选择行
     */
    handleCellClickAll(row) {
      if (!this.endDay < this.today) {
        return
      }
      const selectedData = deepCopy(this.selectedData)
      selectedData[row.userId] = selectedData[row.userId] || {}
      if (Object.keys(selectedData[row.userId]).length) {
        delete selectedData[row.userId]
      } else {
        Object.keys(row.date).forEach((time) => {
          if (time >= this.today) {
            selectedData[row.userId][time] = row.date[time] || row.userName
          }
        })
      }
      this.selectedData = selectedData
    },
    /**
     * 创建 tableData
     */
    createTableData() {
      if (this.headerData.length === 0) {
        return
      }
      const cache = {}
      this.headerData.forEach((header) => {
        this.weeks.forEach((week) => {
          header.date = header.date || {}
          header.date[week.time] = null
        })
        cache[header.userId] = header
      })
      this.contentData.forEach((item) => {
        const { userId, time } = item
        if (cache[userId]) {
          cache[userId].date[time] = item
        }
      })
      this.tableData = Object.values(cache)
    },
    /**
     * 创建星期列表
     */
    createWeeks() {
      const WEEK_NAMES = [
        '星期一',
        '星期二',
        '星期三',
        '星期四',
        '星期五',
        '星期六',
        '星期日',
      ]
      const [start, end] = this.currentWeek
      const startDay = dayjs(start)
      this.endDay = dayjs(end).format('YYYY-MM-DD')
      this.weeks = WEEK_NAMES.map((week, index) => ({
        week,
        time: startDay.add(index, 'day').format('YYYY-MM-DD'),
      }))
    },
    /**
     * 选择时间
     */
    change(date) {
      if (+date !== +this.currentWeek[0]) {
        this.currentWeek = getThisWeekStartWithEnd(date)
        this.selectedData = {}
        this.createWeeks()
        this.$emit('change', this.currentWeek)
      }
    },
    /**
     * 上星期
     */
    prev() {
      this.change(dayjs(this.currentWeek[0]).subtract(1, 'week'))
    },
    /**
     * 下星期
     */
    next() {
      this.change(dayjs(this.currentWeek[0]).add(1, 'week'))
    },
    /**
     * 排班
     */
    work() {
      const workData = []
      Object.values(this.selectedData).forEach((date) => {
        Object.values(date).forEach((value) => {
          if (value && value.id) {
            workData.push(value.id)
          }
        })
      })
      if (workData.length === 0) {
        return
      }
      this.selectedData = {}
      this.$emit('work', workData)
    },
    /**
     * 休息
     */
    rest() {
      const restData = []
      Object.entries(this.selectedData).forEach(([userId, date]) => {
        Object.entries(date).forEach(([time, userName]) => {
          if (typeof userName === 'string') {
            restData.push({
              userName,
              userId: +userId,
              time,
            })
          }
        })
      })
      if (restData.length === 0) {
        return
      }
      this.selectedData = {}
      this.$emit('rest', restData)
    },
  },
}
</script>

<style>
.cell-class-name {
  padding: 0 !important;
}

.cell-class-name .cell {
  padding: 0 !important;
}

.name {
  font-weight: bold !important;
  background-color: #f5f7fa !important;
}

.normal {
  color: #e6a23c !important;
  background-color: #fdf6ec !important;
}

.rest {
  color: #67c23a !important;
  background-color: #f0f9eb !important;
}
</style>

<style lang="scss" scoped>
.top {
  margin-bottom: 15px;
  display: flex;
  justify-content: center;
}

.header {
  display: flex;
  justify-content: center;
  position: relative;
  z-index: 3000;
}

.handler {
  position: relative;
  padding: 8px 10px;

  .mask {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 10;
    background-color: rgba(255, 255, 255, 0.5);
  }
}

.actived {
  background-color: #ecf5ff;
}
</style>
